#include "date_time.h"
#include "date_time_format.hpp"
#include <sys/time.h>

namespace base
{
  namespace utils
  {
    DateTime DateTime::currentDateTime()
    {
      timeval time{};
      int res = gettimeofday(&time, nullptr);
      if (-1 == res)
      {
        return DateTime(std::time(nullptr));
      }
      return DateTime(time.tv_sec, time.tv_usec / 1000);
    }

    long long DateTime::currentSecond()
    {
      return std::time(nullptr);
    }

    DateTime::DateTime()
        : sec(0), msec(0)
    {
    }

    DateTime::DateTime(const base::utils::DateTime &dateTime)
        : sec(dateTime.sec), msec(0)
    {
    }

    DateTime::DateTime(std::tm *tm)
        : sec(std::mktime(tm)), msec(0)
    {
    }

    DateTime::DateTime(long long second)
        : sec(second), msec(0)
    {
    }

    DateTime::DateTime(long long int second, long long int msecond)
        : sec(second), msec(msecond)
    {
    }

    DateTime::~DateTime() = default;

    DateTime DateTime::addDays(int days) const
    {
      DateTime dateTime(this->sec);
      dateTime.sec += days * 24 * 60 * 60;
      return dateTime;
    }
    std::string DateTime::toString(const std::string &format) const
    {
      return base::utils::DateTimeFormat::formatDateTime(format, sec, msec);
    }

    long long DateTime::tm2Second(tm *tm)
    {
      return std::mktime(tm);
      ;
    }
    DateTime DateTime::addSecond(long long int seconds) const
    {
      DateTime dateTime(this->sec);
      dateTime.sec += seconds;
      return dateTime;
    }
    DateTime DateTime::addMillSecond(long long int mill) const
    {
      long long second = mill / 1000;
      int msecond = mill % 1000;
      DateTime dateTime(this->sec);
      dateTime.sec += second;
      dateTime.msec += msecond;
      return dateTime;
    }
    std::tm *DateTime::second2Tm(long long int second)
    {
      return std::localtime((time_t *)&second);
    }
    long long DateTime::toSecond() const
    {
      return (long long)sec;
    }
    long long DateTime::toMilliSecond() const
    {
      return sec * 1000 + msec;
    }

  }
}
